/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package retrofit2;

import static retrofit2.Utils.methodError;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import javax.annotation.Nullable;

/**
 * 看名字 就是接口的方法对应的对象
 *
 * @param <T>
 */
abstract class ServiceMethod<T> {

    /**
     * 解析注解，返回一个方法对应的包装类
     *
     * @param retrofit
     * @param method
     * @param <T>
     * @return
     */
    static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        // 构建一个请求工厂对象 针对方法上的参数、注解信息封装而成
        RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
        // 返回类型
        Type returnType = method.getGenericReturnType();
        // 如果返回是一个未定义的返回 我他妈怎么知道你要返回什么
        if (Utils.hasUnresolvableType(returnType)) {
            throw methodError(
                    method,
                    "Method return type must not include a type variable or wildcard: %s",
                    returnType);
        }
        // 方法不能返回void 必须返回Void对象
        if (returnType == void.class) {
            throw methodError(method, "Service methods cannot return void.");
        }

        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
    }

    abstract @Nullable
    T invoke(Object[] args);
}
